﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://www.codeplex.com/EmlenMud
#if NO_SILVERLIGHT
using System.Runtime.Serialization;
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
#if USE_HYPER
using Hyper.ComponentModel;
#endif
using BrainTechLLC.ThreadSafeObjects;

namespace BrainTechLLC
{
#if NO_SILVERLIGHT
[TypeDescriptionProvider(typeof(HyperTypeDescriptionProvider))]
#endif
    [Serializable]    
    public class PropInfo
    {
        public PropertyInfo PropertyInfo;
        public PropertyDescriptor PropertyDescriptor;
        public ThreadSafeLookupOnDemand<Type, List<Attribute>> AttributeLookup;

        public object GetValue(object thisObject)
        {
            return PropertyDescriptor.GetValue(thisObject);
        }

        public void SetValue(object thisObject, object newVal)
        {
            PropertyDescriptor.SetValue(thisObject, newVal);
        }

        public string Name { get { return PropertyDescriptor.Name; } }

        public PropInfo(PropertyInfo propertyInfo, PropertyDescriptor propertyDescriptor)
        {
            PropertyInfo = propertyInfo;
            PropertyDescriptor = propertyDescriptor;
            object[] attrs = PropertyInfo.GetCustomAttributes(true);

            if (attrs != null && attrs.Length > 0)
            {
                AttributeLookup = new ThreadSafeLookupOnDemand<Type, List<Attribute>>();

                attrs.Cast<Attribute>().ForEach(
                    (attr) => AttributeLookup.Get(attr.GetType()).Add(attr));
            }
        }

        public T[] GetAttributes<T>() where T : class
        {
            List<Attribute> attrs = Attributes(typeof(T));
            if (attrs == null || attrs.Count == 0) return null;
            return attrs.Cast<T>().ToArray();
        }

        public List<Attribute> Attributes(Type t)
        {
            return (AttributeLookup == null) ? null : AttributeLookup.Get(t);
        }
    }
}

#endif